#include "demuxthread.h"

DemuxThread::DemuxThread(QObject *parent, Video* v) :
    QThread(parent)
{
    this->v = v;
    curPTS = 0;
}

void DemuxThread::run() {
    AVPacket packet;
    double vidTBase = av_q2d(v->formatCtx->streams[v->videoIndex]->time_base);
    double audTBase = av_q2d(v->formatCtx->streams[v->audioIndex]->time_base);
    while(true) {
        if (v->state == STOPPED)
            break;
        else if (v->seekFlag) {
            //pause video to stop playing
            VideoState prevState = v->state;
            v->state = SEEKING;
            v->aPacketQueue->flush();
            v->vPacketQueue->flush();
            v->pQueue->flush();
            int streamIndex = -1;
            if (v->videoIndex > 0) streamIndex = v->videoIndex;
            else if (v->audioIndex > 0) streamIndex = v->audioIndex;

            double seekTime = v->seekPos * v->formatCtx->duration / AV_TIME_BASE;
            int64_t seekTarget = (int64_t)(v->seekPos * v->formatCtx->duration);
            if (streamIndex > 0)
                seekTarget = av_rescale_q(seekTarget, AV_TIME_BASE_Q, v->formatCtx->streams[streamIndex]->time_base);

            int flags = seekTime <= v->decodeClock ? AVSEEK_FLAG_BACKWARD : 0;
            av_seek_frame(v->formatCtx, streamIndex, seekTarget, flags);

            //adjust video clock to approximately reflect our decode clock
            v->vidTimeElapsed = 0;
            v->videoClock = seekTime;
            v->countingTime = QTime::currentTime();

            v->seekFlag = false;
            v->state = prevState;
            continue;
        }
        else if (v->state == PAUSED) {
            sleep(0.02);
            continue;
        }
        else if (v->state == PLAY) {
            if (v->vPacketQueue->size >= PacketQueue::MAX_VIDEO_QUEUE_SIZE ||
                v->aPacketQueue->size >= PacketQueue::MAX_AUDIO_QUEUE_SIZE) {
                sleep(0.02);
                continue;
            }

            if (av_read_frame(v->formatCtx, &packet) < 0) {
                v->state = STOPPING;
                break;
            }

            double time;
            if (packet.stream_index==v->videoIndex) {
                v->vPacketQueue->push(&packet);
                time = vidTBase * packet.dts;
                if (v->decodeClock < time)
                    v->decodeClock = time;
            }
            else if (packet.stream_index==v->audioIndex) {
                v->aPacketQueue->push(&packet);
                time = audTBase * packet.dts;
                if (v->decodeClock < time)
                    v->decodeClock = time;
            }
            else
                av_free_packet(&packet);
        }
    }

    std::cout << "demux thread finished" << std::endl;
}
